%load_ext autoreload
%autoreload 2
import sys
sys.path.append('../')
# sys.path.append('/../..')
# sys.path.append('/../')
from keras.backend import clear_session
import matplotlib.pyplot as plt
import numpy as np
from building_classification_package.config import CNN_MODEL_CONFIG, \
VGG_MODEL_CONFIG
from building_classification_package.model_utils import train_model, \
load_trained_and_compiled_model, \
evaluate_model, \
model_predict
#this is needed in dap to unzip the files which are uploaded (unless I moved them already)
# !ls /opt/app-root/s3_home/uploads
# !unzip /opt/app-root/s3_home/uploads/buildings_data_smaller.zip -d data
def get_data_dir(which_set):
return f"../data/Building_labeled_{which_set}_data"
from building_classification_package.data_utils import build_dataset
from building_classification_package.config import DATA_CONFIG
#here I import datasets preprocessed with the function keras uses to preprocess for vgg model
train_iterator = build_dataset(set_to_build='train',
dataset_path=get_data_dir('train'),
validation_split=0.2,
data_config=DATA_CONFIG)
val_iterator = build_dataset(set_to_build='val',
dataset_path = get_data_dir('train'),
validation_split=0.2,
data_config=DATA_CONFIG)
test_iterator = build_dataset(set_to_build='test',
dataset_path = get_data_dir('test'),
data_config=DATA_CONFIG)
#not preprocessed sets:
DATA_CONFIG_NP = DATA_CONFIG.copy()
DATA_CONFIG_NP['preprocessing_fuction'] = None
train_iterator_nop = build_dataset(set_to_build='train',
dataset_path=get_data_dir('train'),
validation_split=0.2,
data_config=DATA_CONFIG_NP)
val_iterator_nop = build_dataset(set_to_build='val',
dataset_path = get_data_dir('train'),
validation_split=0.2,
data_config=DATA_CONFIG_NP)
test_iterator_nop = build_dataset(set_to_build='test',
dataset_path = get_data_dir('test'),
data_config=DATA_CONFIG_NP)
#sets with data augmentation:
train_iterator_aug = build_dataset(set_to_build='train',
dataset_path=get_data_dir('train'),
validation_split=0.2,
data_config=DATA_CONFIG,
shear_range=0.2,zoom_range=0.2,
rotation_range=70,horizontal_flip=True)
val_iterator_aug = build_dataset(set_to_build='val',
dataset_path = get_data_dir('train'),
validation_split=0.2,
data_config=DATA_CONFIG,
shear_range=0.2,zoom_range=0.2,
rotation_range=70,horizontal_flip=True)
test_iterator_aug = build_dataset(set_to_build='test',
dataset_path = get_data_dir('test'),
data_config=DATA_CONFIG,
shear_range=0.2,zoom_range=0.2,
rotation_range=70,horizontal_flip=True)
#check sizes
x_example, y_example = train_iterator[1]
input_shape = x_example[0].shape #the input shape should not include batch size
n_classes = y_example[0].shape[0]
print('size of each image: ', input_shape)
print('number of classes: ', n_classes)
X_train, y_train = train_iterator[1]
X_val, y_val = val_iterator[1]
X_test, y_test = test_iterator[1]
print ('X_train: ', X_train.shape,
'\ny_train: ', y_train.shape,
'\nX_val: ', X_val.shape,
'\ny_val: ', y_val.shape,
'\nX_test: ', X_test.shape,
'\ny_test: ', y_test.shape)
#print an example (both preprocessed and not preprocessed)
x,y = train_iterator[0]
x_nop, y_nop = train_iterator_nop[0]
for i in range(0,1):
image = x[i]
image_nop = x_nop[i]
plt.imshow(image_nop)
plt.show()
print('processed:')
plt.imshow(image)
plt.show()
#print an example (with and without augmentation)
x_aug, y_aug = train_iterator_aug[0]
for i in range(0,1):
image = x[i]
image_aug = x_aug[i]
plt.imshow(image)
plt.show()
print('augmented:')
plt.imshow(image_aug)
plt.show()
The first model I try is a simple CNN model with 2 convolution layers
clear_session()
train_model(train_data=train_iterator,
val_data=val_iterator,
model_config=CNN_MODEL_CONFIG)
#loss and accuracy:
print('validation set:')
print(evaluate_model(val_data = val_iterator, model_config=CNN_MODEL_CONFIG))
#accuracy on test
print ('test set:')
evaluate_model(val_data = test_iterator, model_config=CNN_MODEL_CONFIG)
cnn_predictions = model_predict(CNN_MODEL_CONFIG, val_iterator)
cnn_predictions
The second model I try is based on pre-trained VGG16 as base model.
clear_session()
from building_classification_package.config import VGG_MODEL_CONFIG
train_model(train_iterator, val_iterator, VGG_MODEL_CONFIG)
#loss and accuracy
print('validation set:')
print(evaluate_model(val_data = val_iterator, model_config=VGG_MODEL_CONFIG))
#on unseen test set
print('test set:')
evaluate_model(val_data = test_iterator, model_config=VGG_MODEL_CONFIG)
vgg_predictions = model_predict(VGG_MODEL_CONFIG, val_iterator)
vgg_predictions
labels = val_iterator.class_indices
labels_flip = {value:key for key, value in labels.items()}
labels_flip
#real y values of validation set
real_y = val_iterator.labels
#extract some images and their labels
val_iterator.reset()
val_sample = [next(val_iterator_nop) for _ in range(150)]
x_val_no_p = [x[0] for x in val_sample]
#prediction on validation set
pred_proba = vgg_predictions
pred = [np.argmax(x) for x in pred_proba]
#some examples of correctly labeled images
for p, image, y, probs in zip(pred, x_val_nop, real_y, pred_proba):
if p == y:
print(f'{labels_flip[y]} predicted as {labels_flip[p]}')
print(f'probabilities: {labels_flip[0]} {np.round(probs[0], 3)}, \
\n {labels_flip[1]} {np.round(probs[1], 3)}, \
\n {labels_flip[2]} {np.round(probs[2], 3)}, \
\n {labels_flip[3]} {np.round(probs[3], 3)}, \
\n {labels_flip[4]} {np.round(probs[4], 3)}')
plt.imshow(image)
plt.show()
#some examples of mislabeled images
for p, image, y, probs in zip(pred, x_val_nop, real_y, pred_proba):
if p != y:
print(f'{labels_flip[y]} predicted as {labels_flip[p]}')
print(f'probabilities: {labels_flip[0]} {np.round(probs[0], 3)}, \
\n {labels_flip[1]} {np.round(probs[1], 3)}, \
\n {labels_flip[2]} {np.round(probs[2], 3)}, \
\n {labels_flip[3]} {np.round(probs[3], 3)}, \
\n {labels_flip[4]} {np.round(probs[4], 3)}')
plt.imshow(image)
plt.show()
from sklearn.metrics import classification_report, confusion_matrix
print(classification_report(real_y, pred, target_names=labels))
sns.heatmap(confusion_matrix(real_y, pred))
plt.xlabel('predicted class')
plt.ylabel('real class')
plt.xticks(ticks=[x + 0.5 for x in list(labels_flip.keys())], labels=list(labels_flip.values()), rotation=90);
plt.yticks(ticks=[x + 0.5 for x in list(labels_flip.keys())], labels=list(labels_flip.values()), rotation=0);
industrial is the easiest one to classify correctly, followed by house.
retail and apartment are hardest to classify corretly (also by hand, I noticed, as they are the most ambiguous).